# This makefile is used to a limited degree with nmake, but it mostly
# intended for use as a GNU makefile.

RACKET = ../../bin/racket
SCHEME = scheme

# Controls whether Racket layers are built as unsafe; beware that
# building some Racket libraries using safe mode may require setting
# `PLT_CS_COMPILE_LIMIT` to 1000 (instead of 10000):
UNSAFE_COMP = --unsafe

# Controls whether compiled code is compressed:
COMPRESS_COMP = # --compress

# Controls whether Racket layers are built with expression-level
# debugging; use "--debug" for expression-level information or
# "--srcloc" for procedure-level source locations:
DEBUG_COMP = # --debug

# To disable whole-program optimization for "main.sps", set
# `WHEN_WPO=no_` and `UNLESS_WPO=`.
WHEN_WPO =
UNLESS_WPO = no_

# For cross-compiling, set `CROSS_COMP` to `-m <machine>`, where
# the Chez Scheme directory must have "<machine>/s/xpatch":
CROSS_COMP =

# Can be set by a caller:
EXTRA_COMPILE_DEPS = 

COMPILE_FILE = $(SCHEME) --script compile-file.ss $(UNSAFE_COMP) $(COMPRESS_COMP) $(DEBUG_COMP) $(CROSS_COMP) --dest "$(BUILDDIR)"
COMPILE_FILE_DEPS = compile-file.ss include.ss place-register.ss $(EXTRA_COMPILE_DEPS)

RACKET_SETUP_ARGS = false ../../bin/racket ../../bin/racket ../collects ../etc "" 0 false false 0 ""

PRIMITIVES_TABLES = primitive/kernel.ss primitive/unsafe.ss primitive/flfxnum.ss \
                    primitive/paramz.ss primitive/extfl.ss primitive/network.ss \
                    primitive/futures.ss primitive/foreign.ss primitive/place.ss \
                    primitive/linklet.ss primitive/terminal.ss primitive/internal.ss

# Set by the makefile in the "c" directory when driving this one
BUILDDIR =

# Set by the makefile in the "c" directory when driving this one to
# avoid trying to re-build bootstrapped files:
BOOTSTRAPPED = schemified

# List all targets ".scm" that use "convert.rkt" so we can generate a
# dependency rule for all of them:
CONVERTED = schemified/thread.scm schemified/io.scm \
            schemified/regexp.scm schemified/expander.scm \
            schemified/schemify.scm schemified/known.scm

# Additional dependencies for those ".scm" files generated by "convert.rkt":
CONVERT_DEPS = $(PRIMITIVES_TABLES)

CONVERT_RACKET = $(RACKET) -l- setup --chain ../setup-go.rkt $(BUILDDIR)compiled
CONVERT = $(CONVERT_RACKET) '(CONVERTED)' $(BUILDDIR)compiled/convert.d convert.rkt $(UNSAFE_COMP)

# This extension is for libraries, and it changes for cross builds:
CSO = so

# Depenency chain for ".so" files:
RUMBLE_DEPS = $(BUILDDIR)chezpart.$(CSO)
THREAD_DEPS = $(RUMBLE_DEPS) $(BUILDDIR)rumble.$(CSO)
IO_DEPS = $(THREAD_DEPS) $(BUILDDIR)thread.$(CSO)
REGEXP_DEPS = $(IO_DEPS) $(BUILDDIR)io.$(CSO)
SCHEMIFY_DEPS = $(REGEXP_DEPS) $(BUILDDIR)regexp.$(CSO)
LINKLET_DEPS = $(SCHEMIFY_DEPS) $(BUILDDIR)schemify.$(CSO)
EXPANDER_DEPS = $(LINKLET_DEPS) $(BUILDDIR)linklet.$(CSO)
MAIN_DEPS = $(EXPANDER_DEPS) $(BUILDDIR)expander.$(CSO)

converted: $(CONVERTED)

all:
	$(MAKE) rktio
	$(MAKE) rktl
	$(MAKE) $(BUILDDIR)racket.so

CROSS_TARGET = all
cross:
	$(MAKE) $(CROSS_TARGET) CSO=$(HOST) CROSS_COMP="--xpatch $(XPATCH)"

expander-demo: $(BUILDDIR)expander.$(CSO) demo/expander.ss ../../bin/racket
	$(SCHEME) $(EXPANDER_DEPS) $(BUILDDIR)expander.$(CSO) demo/expander.ss

run: $(BUILDDIR)main.so ../../bin/racket
	$(SCHEME) --script $(BUILDDIR)main.so $(RACKET_SETUP_ARGS) $(ARGS)

setup:
	$(MAKE) run ARGS="-l- setup $(ARGS)"

setup-v:
	$(MAKE) run ARGS="-W 'info@compiler/cm info@linklet debug@GC:major error' -l- setup -j 1 $(ARGS)"

run-wpo: $(BUILDDIR)racket.so ../../bin/racket
	$(SCHEME) --script $(BUILDDIR)racket.so $(RACKET_SETUP_ARGS) $(ARGS)

$(WHEN_WPO)$(BUILDDIR)racket.so: $(BUILDDIR)main.so $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) --whole-program $(BUILDDIR)racket.so $(BUILDDIR)main.wpo

$(UNLESS_WPO)$(BUILDDIR)racket.so: $(BUILDDIR)main.so $(COMPILE_FILE_DEPS)
	cat $(MAIN_DEPS) $(BUILDDIR)main.so > $(BUILDDIR)racket.so

MAIN_SRCS = main/help.ss

$(BUILDDIR)main.so: $(MAIN_DEPS) main.sps $(MAIN_SRCS) $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) main.sps $(MAIN_DEPS)

strip:
	$(SCHEME) --script strip.ss $(MAIN_DEPS) $(BUILDDIR)racket.so

rktl:
	$(MAKE) thread-rktl
	$(MAKE) io-rktl
	$(MAKE) regexp-rktl
	$(MAKE) schemify-rktl
	$(MAKE) known-rktl
	$(MAKE) expander-rktl

# For running without an enclosing build of the traditional Racket VM:
../../bin/racket:
	mkdir -p ../../bin
	touch ../../bin/racket

$(BUILDDIR)expander.$(CSO): expander.sls expander/env.ss schemified/expander.scm $(PRIMITIVES_TABLES) $(EXPANDER_DEPS) $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) expander.sls $(EXPANDER_DEPS)

$(BOOTSTRAPPED)/expander.scm: $(BUILDDIR)compiled/expander.rktl $(CONVERT_DEPS)
	$(CONVERT) $(BUILDDIR)compiled/expander.rktl $(BOOTSTRAPPED)/expander.scm

$(BUILDDIR)compiled/expander.rktl:
	$(MAKE) expander-rktl

expander-rktl:
	$(MAKE) bounce BOUNCE_DIR=../expander BOUNCE_TARGET=expander-src BUILDDIR="../cs/"

linklet-demo: $(BUILDDIR)linklet.$(CSO)
	$(SCHEME) $(LINKLET_DEPS) $(BUILDDIR)linklet.$(CSO) demo/linklet.ss

LINKLET_SRCS = linklet/version.ss \
               linklet/read.ss \
               linklet/write.ss \
               linklet/check.ss \
               linklet/performance.ss \
               linklet/annotation.ss \
               linklet/compress.ss \
               linklet/config.ss \
               linklet/cross-compile.ss

$(BUILDDIR)linklet.$(CSO): linklet.sls $(LINKLET_SRCS) $(LINKLET_DEPS) $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) linklet.sls $(LINKLET_DEPS)


$(BUILDDIR)schemify.$(CSO): schemify.sls schemified/schemify.scm schemified/known.scm $(PRIMITIVES_TABLES) $(SCHEMIFY_DEPS) $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) schemify.sls $(SCHEMIFY_DEPS)

$(BOOTSTRAPPED)/schemify.scm: $(BUILDDIR)compiled/schemify.rktl $(CONVERT_DEPS)
	$(CONVERT) --skip-export $(BUILDDIR)compiled/schemify.rktl $(BOOTSTRAPPED)/schemify.scm

$(BUILDDIR)compiled/schemify.rktl:
	$(MAKE) schemify-rktl

schemify-rktl:
	$(MAKE) bounce BOUNCE_DIR=../schemify BOUNCE_TARGET=schemify-src BUILDDIR="../cs/"


# Used by schemify.sls at compile time
$(BOOTSTRAPPED)/known.scm: $(BUILDDIR)compiled/known.rktl $(CONVERT_DEPS)
	$(CONVERT) --skip-export $(BUILDDIR)compiled/known.rktl $(BOOTSTRAPPED)/known.scm

$(BUILDDIR)compiled/known.rktl:
	$(MAKE) known-rktl

known-rktl:
	$(MAKE) bounce BOUNCE_DIR=../schemify BOUNCE_TARGET=known-src BUILDDIR="../cs/"


regexp-demo: $(BUILDDIR)regexp.$(CSO)
	$(SCHEME) $(REGEXP_DEPS) $(BUILDDIR)regexp.$(CSO) demo/regexp.ss

$(BUILDDIR)regexp.$(CSO): schemified/regexp.scm regexp.sls $(REGEXP_DEPS) $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) regexp.sls $(REGEXP_DEPS)

$(BOOTSTRAPPED)/regexp.scm: $(BUILDDIR)compiled/regexp.rktl $(CONVERT_DEPS)
	$(CONVERT) $(BUILDDIR)compiled/regexp.rktl $(BOOTSTRAPPED)/regexp.scm

$(BUILDDIR)compiled/regexp.rktl:
	$(MAKE) regexp-rktl

regexp-rktl:
	$(MAKE) bounce BOUNCE_DIR=../regexp BOUNCE_TARGET=regexp-src BUILDDIR="../cs/"


io-demo: $(BUILDDIR)io.$(CSO)
	$(SCHEME) $(IO_DEPS) $(BUILDDIR)io.$(CSO) demo/io.ss

$(BUILDDIR)io.$(CSO): schemified/io.scm io.sls io/terminal.ss $(IO_DEPS) ../rktio/rktio.rktl $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) io.sls $(IO_DEPS)

$(BOOTSTRAPPED)/io.scm: $(BUILDDIR)compiled/io.rktl $(CONVERT_DEPS)
	$(CONVERT) $(BUILDDIR)compiled/io.rktl $(BOOTSTRAPPED)/io.scm

$(BUILDDIR)compiled/io.rktl:
	$(MAKE) io-rktl

io-rktl:
	$(MAKE) bounce BOUNCE_DIR=../io BOUNCE_TARGET=io-src BUILDDIR="../cs/"

rktio:
	$(MAKE) bounce BOUNCE_DIR=../io BOUNCE_TARGET=rktio


thread-demo: $(BUILDDIR)thread.$(CSO)
	$(SCHEME) $(THREAD_DEPS) $(BUILDDIR)thread.$(CSO) demo/thread.ss

$(BUILDDIR)thread.$(CSO): schemified/thread.scm thread.sls $(THREAD_DEPS) $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) thread.sls $(THREAD_DEPS)

$(BOOTSTRAPPED)/thread.scm: $(BUILDDIR)compiled/thread.rktl $(CONVERT_DEPS)
	$(CONVERT) $(BUILDDIR)compiled/thread.rktl $(BOOTSTRAPPED)/thread.scm

$(BUILDDIR)compiled/thread.rktl:
	$(MAKE) thread-rktl

thread-rktl:
	$(MAKE) bounce BOUNCE_DIR=../thread BOUNCE_TARGET=thread-src BUILDDIR="../cs/"


bounce:
	$(MAKE) bounce-go RACKET="`$(RACKET) absify.rkt --exec $(RACKET)`"

bounce-go:
	cd $(BOUNCE_DIR); $(MAKE) RACO="$(RACKET) -N raco -l- raco" $(BOUNCE_TARGET)


chaperone-demo: $(BUILDDIR)rumble.$(CSO)
	$(SCHEME) $(BUILDDIR)chezpart.$(CSO) $(BUILDDIR)rumble.$(CSO) demo/chaperone.ss

hash-demo: $(BUILDDIR)rumble.$(CSO)
	$(SCHEME) $(BUILDDIR)chezpart.$(CSO) $(BUILDDIR)rumble.$(CSO) demo/hash.ss

struct-demo: $(BUILDDIR)rumble.$(CSO)
	$(SCHEME) $(BUILDDIR)chezpart.$(CSO) $(BUILDDIR)rumble.$(CSO) demo/struct.ss

control-demo: $(BUILDDIR)rumble.$(CSO)
	$(SCHEME) $(BUILDDIR)chezpart.$(CSO) $(BUILDDIR)rumble.$(CSO) demo/control.ss

foreign-demo: $(BUILDDIR)rumble.$(CSO)
	$(SCHEME) $(BUILDDIR)chezpart.$(CSO) $(BUILDDIR)rumble.$(CSO) demo/foreign.ss

will-demo: $(BUILDDIR)rumble.$(CSO)
	$(SCHEME) $(BUILDDIR)chezpart.$(CSO) $(BUILDDIR)rumble.$(CSO) demo/will.ss

future-demo: $(BUILDDIR)rumble.$(CSO)
	$(SCHEME) $(BUILDDIR)chezpart.$(CSO) $(BUILDDIR)rumble.$(CSO) demo/future.ss

future2-demo: $(BUILDDIR)rumble.$(CSO)
	$(SCHEME) $(BUILDDIR)chezpart.$(CSO) $(BUILDDIR)rumble.$(CSO) demo/future2.ss

RUMBLE_SRCS = rumble/virtual-register.ss \
              rumble/check.ss \
	      rumble/syntax-rule.ss \
              rumble/constant.ss \
              rumble/hash-code.ss \
              rumble/struct.ss \
              rumble/prefab.ss \
              rumble/procedure.ss \
              rumble/impersonator.ss \
              rumble/equal.ss \
              rumble/object-name.ss \
              rumble/arity.ss \
              rumble/intmap.ss \
              rumble/patricia.ss \
              rumble/hamt-stencil.ss \
              rumble/hamt-vector.ss \
              rumble/hash.ss \
              rumble/datum.ss \
	      rumble/lock.ss \
	      rumble/thread-local.ss \
              rumble/thread-cell.ss \
              rumble/parameter.ss \
              rumble/begin0.ss \
              rumble/value.ss \
              rumble/pthread.ss \
              rumble/control.ss \
              rumble/interrupt.ss \
              rumble/engine.ss \
              rumble/source.ss \
              rumble/error.ss \
              rumble/error-rewrite.ss \
              rumble/srcloc.ss \
              rumble/boolean.ss \
              rumble/bytes.ss \
              rumble/string.ss \
              rumble/char.ss \
              rumble/char-range.ss \
              rumble/symbol.ss \
              rumble/list.ss \
              rumble/vector.ss \
              rumble/box.ss \
              rumble/immutable.ss \
              rumble/keyword.ss \
              rumble/mpair.ss \
              rumble/number.ss \
              rumble/random.ss \
              rumble/flvector.ss \
              rumble/correlated.ss \
              rumble/graph.ss \
              rumble/time.ss \
              rumble/memory.ss \
              rumble/ephemeron.ss \
              rumble/will-executor.ss \
              rumble/system.ss \
              rumble/unsafe.ss \
              rumble/extfl.ss \
              rumble/place.ss \
              rumble/errno-data.ss \
              rumble/foreign.ss \
              rumble/async-callback.ss \
              rumble/future.ss \
              rumble/version.ss \
              rumble/inline.ss \
              ../version/racket_version.h

$(BUILDDIR)rumble.$(CSO): $(RUMBLE_DEPS) rumble.sls $(RUMBLE_SRCS) $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) rumble.sls $(RUMBLE_DEPS)

$(BUILDDIR)chezpart.$(CSO): chezpart.sls $(COMPILE_FILE_DEPS)
	$(COMPILE_FILE) chezpart.sls

clean:
	rm -f chezpart.$(CSO) rumble.$(CSO) regexp.$(CSO) io.$(CSO) linklet.$(CSO) expander.$(CSO) schemify.$(CSO)
	rm -f chezpart.so rumble.so regexp.so io.so linklet.so expander.so schemify.so
	rm -f chezpart.wpo rumble.wpo regexp.wpo io.wpo linklet.wpo expander.wpo schemify.wpo
	rm -f thread.$(CSO) thread.wpo main.wpo main.so
	rm -rf compiled


# The following included dependency files are generated by when
# creating compiler/expander.rktl, etc. The `-inclide` statements are
# wrapped in a pattern that causes them to be ignored by `nmake`,
# while the `nmake` directives are ignored by GNU `make`.

# \
!if 0

# These dependencies are used only for direct use of the makefile
-include compiled/expander.d
-include compiled/thread.d
-include compiled/io.d
-include compiled/regexp.d
-include compiled/schemify.d
-include compiled/known.d

# These dependencies are needed when "cs/c" drives the makefile
-include $(BUILDDIR)compiled/convert.d

#\
!endif

# \
!include $(BUILDDIR)compiled/convert.d
